package org.lgiavedoni.android.franq.core.sync;

import java.util.List;

import org.lgiavedoni.android.franq.core.dao.DaoObject;
import org.lgiavedoni.android.franq.core.sync.imp.GenericDao;
import org.lgiavedoni.android.franq.service.log.Logger;

public abstract class AbstractSyncProcess {

	public void sync() {
		Logger.inst.info("Synchronization for " + getClass().getSimpleName() + " --> STARTED");
		if (!init()) {
			Logger.inst.error("Unexpected error in the init method of the Synchronization process " + getClass().getSimpleName());
		}
		for (Synchronizable obj : getObjectsForParcialSynchronization()) {
			if (!obj.isSyncronized()) {
				Logger.inst.debug("Synchronizing obj[" + obj + "]");
				if (syncronizeObj(obj)) {
					obj.setSyncronized(true);
					if (obj instanceof DaoObject)
						GenericDao.inst.update((DaoObject) obj);
				}
			}
		}

		Logger.inst.info("Synchronization for " + getClass().getSimpleName() + " --> END");
	}

	public abstract boolean init();

	public abstract Class getObjectClass();

	public abstract boolean syncronizeObj(Synchronizable obj);

	protected List<Synchronizable> getObjectsForParcialSynchronization() {
		return GenericDao.inst.getAllNoSyncronized(getObjectClass());
	}

	protected List<DaoObject> getObjectsForTotalSynchronization() {
		return GenericDao.inst.getAll(getObjectClass());
	}

	public void reset() {
		for (DaoObject synchronizable : getObjectsForTotalSynchronization()) {
			if (synchronizable instanceof DaoSynObject && ((DaoSynObject) synchronizable).isSyncronized()) {
				((DaoSynObject) synchronizable).setSyncronized(false);
				GenericDao.inst.update(synchronizable);
			}
		}
		resetInternal();
	}

	protected abstract void resetInternal();

}
